﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CanvasEx.DrawCore;


namespace CanvasEx
{
    public class Painter
    {
        internal TransformGroup tfGroup = new TransformGroup();
        internal TranslateTransform Translate = new TranslateTransform();//偏移量
        internal ScaleTransform Scale = new ScaleTransform();//缩放量
        internal double scaleLevel = 1.1;//缩放级别
        internal double SelectAccuracy = 2;
        //double hotspotSize = 3;

        private MyCanvas cv;
        Color pColor = Colors.White;
        public List<DrawObject> DrawList = new List<DrawObject>();
        List<HotSpot> HotSpotList = new List<HotSpot>();

        //Dictionary<DrawObject, BaseTool> ToolsDic = new Dictionary<DrawObject, BaseTool>();

        public Painter(MyCanvas cv)
        {
            this.cv = cv;

            cv.MouseLeftButtonDown += new MouseButtonEventHandler(Canvas_MouseLeftButtonDown);
            cv.MouseRightButtonDown += new MouseButtonEventHandler(Canvas_MouseRightButtonDown);
            cv.MouseRightButtonUp += new MouseButtonEventHandler(Canvas_MouseRightButtonUp);
            cv.MouseMove += new MouseEventHandler(Canvas_MouseMove);
            cv.MouseWheel += new MouseWheelEventHandler(Canvas_MouseWheel);


            tfGroup.Children.Add(Translate);
            tfGroup.Children.Add(Scale);
            Scale.ScaleY = -1;
            Translate.Y = -cv.Height;

        }

        public Color Color
        {
            get { return pColor; }
            set { pColor = value; }
        }




        public void DrawEvent()
        {
            cv.Children.Clear();
            foreach (DrawObject obj in DrawList)
            {
                cv.Children.Add(obj.path);
            }
        }



        bool isMouseRightButtonDown = false;
        //鼠标位置
        Point MousePosition;
        Point OldMousePosition;

        private Point TranslateLocation(Point Location)
        {
            Location.X -= Translate.X * Scale.ScaleX;
            Location.Y -= Translate.Y * Scale.ScaleY;
            Location.X /= Scale.ScaleX;
            Location.Y /= Scale.ScaleY;
            return Location;
        }
        private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Point Location = e.GetPosition(cv);
            Location = TranslateLocation(Location);

            if (!(System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Control))
            {
                HotSpotList.Clear();
            }
        }

        private void Canvas_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            isMouseRightButtonDown = true;
        }

        private void Canvas_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            isMouseRightButtonDown = false;
        }

        private static Point deltaPt = new Point(0, 0);
        private void Canvas_MouseMove(object sender, MouseEventArgs e)
        {
            MousePosition = e.GetPosition(cv);
            if (isMouseRightButtonDown)
            {
                deltaPt.X = (MousePosition.X - OldMousePosition.X);
                deltaPt.Y = (MousePosition.Y - OldMousePosition.Y);
                MoveTo(deltaPt);
            }
            OldMousePosition.X = MousePosition.X;
            OldMousePosition.Y = MousePosition.Y;
        }

        public void MoveTo(Point deltaPt)
        {
            Translate.X += deltaPt.X / Scale.ScaleX;
            Translate.Y += deltaPt.Y / Scale.ScaleY;
        }

        private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            Point Location = e.GetPosition(cv);
            if (e.Delta > 0)
            {
                Scale.ScaleX *= scaleLevel;
                Scale.ScaleY *= scaleLevel;
                MoveTo(new Point(Location.X * -(scaleLevel - 1), Location.Y * -(scaleLevel - 1)));
                if (SelectAccuracy > 0.02)
                    SelectAccuracy /= scaleLevel;
            }
            else
            {
                MoveTo(new Point(Location.X * (scaleLevel - 1), Location.Y * (scaleLevel - 1)));
                Scale.ScaleX /= scaleLevel;
                Scale.ScaleY /= scaleLevel;
                if (SelectAccuracy < 2)
                    SelectAccuracy *= scaleLevel;
            }

        }

        public void AddPoint(Point point)
        {
            DrawList.Add(new DrawPoint(this, point));
        }
        public void AddLine(Point sta, Point end)
        {
            DrawList.Add(new DrawLine(this, sta, end));
        }
        public void AddArc(Point sta, Point end, Point center, SweepDirection dir)
        {
            DrawList.Add(new DrawArc(this, sta, end, center, dir));
        }
        public void AddRectangle(Point left_top, Point right_bottom)
        {
            DrawList.Add(new DrawRectangle(this, left_top, right_bottom));
        }
        public void AddEllipse(Point center, double r)
        {
            DrawList.Add(new DrawEllipse(this, center, r));
        }
        public void AddPolyLine(List<Point> pointlist)
        {
            DrawList.Add(new DrawPolyLine(this, pointlist));
        }

    }
}
